package com.example.myweb.Config;

import com.example.myweb.Security.CustomUserDetailsService;
import com.example.myweb.Security.JwtAuthenticationFilter;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

@Configuration
@EnableWebSecurity // 启用Spring Security的Web安全功能
//@EnableGlobalMethodSecurity(prePostEnabled = true) // 启用方法级别的安全注解
@EnableMethodSecurity(prePostEnabled = true)
@RequiredArgsConstructor
public class SecurityConfig {
//
//    @Autowired
//    private JwtAuthenticationFilter jwtAuthFilter; // 注入JWT认证过滤器
//
//    @Autowired
//    private CustomUserDetailsService customUserDetailsService; // 注入自定义用户详情服务
//
//    @Autowired
//    private  AuthenticationProvider authenticationProvider;
//
//    @Autowired
//    private CorsProperties corsProperties; // 注入CorsProperties来读取跨域配置

    private final JwtAuthenticationFilter jwtAuthFilter;
    private final CustomUserDetailsService customUserDetailsService;
    private final CorsProperties corsProperties;


    // 1. 定义密码编码器Bean
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    // 2. 定义认证提供者Bean
    @Bean
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(customUserDetailsService); // 设置自定义UserDetailsService
        authProvider.setPasswordEncoder(passwordEncoder()); // 设置密码编码器

        return authProvider;
    }

    // 3. 定义认证管理器Bean
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }

    // 4. 配置 CORS 源 (用于前后端分离)
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
//
//        CorsConfiguration configuration = new CorsConfiguration();
//        String allowedMethods = corsProperties.getAllowedMethods();
//        configuration.setAllowedOrigins(Arrays.asList("http://localhost:5173"));
//        // 允许所有请求方法 (GET, POST, PUT, DELETE, etc.)
//        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
//        // 允许所有请求头
//        configuration.setAllowedHeaders(Arrays.asList("*"));
//        // 允许浏览器发送凭证 (如 cookies, authorization headers)
//        configuration.setAllowCredentials(true);
//
//        // 如果 allowedMethods 为 null，默认赋值为允许所有方法
//        if (allowedMethods == null) {
//            configuration.addAllowedMethod("*");
//        } else {
//            configuration.setAllowedMethods(Arrays.asList(allowedMethods.split(",")));
//        }
//
//        // 允许的来源，从properties读取并分割
//        configuration.setAllowedOrigins(Arrays.asList(corsProperties.getAllowedOrigins()));
//        configuration.setAllowedMethods(Arrays.asList(corsProperties.getAllowedMethods()));
//        String allowedHeaders = corsProperties.getAllowedHeaders();
//        if (allowedHeaders != null) {
//            configuration.setAllowedHeaders(Arrays.asList(allowedHeaders.split(",")));
//        } else {
//            configuration.setAllowedHeaders(Collections.emptyList());
//        }
//        // 是否允许发送凭证（如Cookies, Authorization头）
//        configuration.setAllowCredentials(corsProperties.isAllowCredentials());
//        // 预检请求的缓存时间
//        configuration.setMaxAge(corsProperties.getMaxAge());
//
//        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
//        source.registerCorsConfiguration("/**", configuration); // 对所有路径生效
//        return source;

        CorsConfiguration configuration = new CorsConfiguration();

//        // 允许的来源 - 添加5174端口
//        configuration.setAllowedOrigins(Arrays.asList(
//                "http://localhost:5173",
//                "http://localhost:5174"
//        ));
//
//        // 允许所有请求方法
//        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
//
//        // 允许所有请求头
//        configuration.setAllowedHeaders(Arrays.asList("*"));
//
//        // 允许浏览器发送凭证
//        configuration.setAllowCredentials(true);
//
//        // 预检请求的缓存时间
//        configuration.setMaxAge(3600L);
//
//        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
//        source.registerCorsConfiguration("/**", configuration);
//        return source;
        // 支持配置多个源，用逗号分隔
        configuration.setAllowedOrigins(Arrays.asList(corsProperties.getAllowedOrigins().split(",")));

        // 支持配置多个方法，确保包含了所有写操作和OPTIONS
        configuration.setAllowedMethods(Arrays.asList(corsProperties.getAllowedMethods().split(",")));

        // 允许所有请求头
        configuration.setAllowedHeaders(Arrays.asList("*"));

        // 允许携带凭证
        configuration.setAllowCredentials(corsProperties.isAllowCredentials());

        // 预检请求的有效期
        configuration.setMaxAge(corsProperties.getMaxAge());

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration); // 对所有路径应用此配置
        return source;
    }


    // 5. 配置安全过滤链
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
//        http
//                .csrf(AbstractHttpConfigurer::disable)
//                .cors(cors -> cors.configurationSource(corsConfigurationSource()))
//                .authorizeHttpRequests(authorize -> authorize
//                        // 允许注册和登录
//                        .requestMatchers(new AntPathRequestMatcher("/user/register")).permitAll()
//                        .requestMatchers(new AntPathRequestMatcher("/user/login")).permitAll()
//                        .requestMatchers(new AntPathRequestMatcher("/register")).permitAll()
//                        .requestMatchers(new AntPathRequestMatcher("/login")).permitAll()
//                        // 其他认证相关的公共接口 (例如 /user/forgot-password, /user/reset-password)
//                        .requestMatchers(new AntPathRequestMatcher("/user/forgot-password")).permitAll()
//                        .requestMatchers(new AntPathRequestMatcher("/user/reset-password")).permitAll()
//                        .requestMatchers(new AntPathRequestMatcher("/user/logout")).authenticated() // 登出需要认证
//                        // 获取和更新个人资料需要认证
//                        .requestMatchers(new AntPathRequestMatcher("/user/me")).authenticated()
//                        .requestMatchers(new AntPathRequestMatcher("/user/me", HttpMethod.PUT.name())).authenticated()
//                        // 任何其他请求都需要认证
//                        // 放行所有公共的、只读的(GET)内容接口
//                        .antMatchers(HttpMethod.GET,
//                                "/feed",
//                                "/articles",
//                                "/articles/{id}",
//                                "/dynamics",
//                                "/dynamics/{id}",
//                                "/dynamics/{id}/comments",
//                                "/articles/{id}/comments"
//                        ).permitAll()
//                        .antMatchers("/admin/**").hasRole("ADMIN")
//
//                        // 3. 【关键】放行我们新的“查看他人主页”接口
//                        .antMatchers(HttpMethod.GET, "/user/{id}/profile").permitAll()
//                        .anyRequest().authenticated()
//                )
//                .sessionManagement(session -> session
//                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
//                )
//                .authenticationProvider(authenticationProvider())
//                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
//        return http.build();
//        http
//                .csrf(AbstractHttpConfigurer::disable)
//                .cors(cors -> cors.configurationSource(corsConfigurationSource()))
//                .authorizeHttpRequests(authorize -> authorize
//                        // 允许注册和登录
//                         // 允许注册和登录
//                        .requestMatchers(new AntPathRequestMatcher("/user/register")).permitAll()
//                        .requestMatchers(new AntPathRequestMatcher("/user/login")).permitAll()
//                        .requestMatchers(new AntPathRequestMatcher("/register")).permitAll()
//                        .requestMatchers(new AntPathRequestMatcher("/login")).permitAll()
//                         //其他认证相关的公共接口 (例如 /user/forgot-password, /user/reset-password)
//                        .requestMatchers(new AntPathRequestMatcher("/user/reset-password")).permitAll()
//                        .requestMatchers(new AntPathRequestMatcher("/user/logout")).authenticated() // 登出需要认证
//                        // 获取和更新个人资料需要认证
//                        .requestMatchers(new AntPathRequestMatcher("/user/me")).authenticated()
//                        .requestMatchers(new AntPathRequestMatcher("/user/me", HttpMethod.PUT.name())).authenticated()
//                        // 放行公共的只读内容接口
//                        .antMatchers(HttpMethod.GET,
//                                "/feed",
//                                "/articles",
//                                "/articles/{id}",
//                                "/dynamics",
//                                "/dynamics/{id}",
//                                "/dynamics/{id}/comments",
//                                "/articles/{id}/comments"
//                        ).permitAll()
//
//                        .antMatchers("/admin/**").hasRole("ADMIN")
//                        .anyRequest().authenticated()
//                )
//                .sessionManagement(session -> session
//                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
//                )
//                .authenticationProvider(authenticationProvider())
//                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
//        return http.build();
        // 修改后的 SecurityFilterChain 配置
//        http
//                .csrf(AbstractHttpConfigurer::disable)
//                .logout(AbstractHttpConfigurer::disable)
//                .cors(cors -> cors.configurationSource(corsConfigurationSource()))
//                .sessionManagement(session -> session
//                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
//                )
//
//                // 完整的、修正后的 authorizeHttpRequests 配置
//                // 完整的、修正后的 authorizeHttpRequests 配置
//                .authorizeHttpRequests(authorize -> {
//                    // 1. 定义所有需要公开访问的路径
//                    String[] publicPaths = {
//                            "/user/register",
//                            "/user/login",
//                            "/user/forgot-password",
//                            "/user/reset-password"
//                    };
//                    String[] publicGetPaths = {
//                            "/feed",
//                            "/articles",
//                            "/articles/{id}",
//                            "/dynamics",
//                            "/dynamics/{id}",
//                            "/{contentType}/{contentId}/comments"
//                    };
//
//                    authorize
//                            // 2. 将路径数组转换为 RequestMatcher 数组并应用权限
//                            .requestMatchers(new AntPathRequestMatcher("/user/logout")).permitAll()
//                            .requestMatchers(
//                                    Stream.of(publicPaths).map(AntPathRequestMatcher::new).toArray(AntPathRequestMatcher[]::new)
//                            ).permitAll()
//                            .requestMatchers(
//                                    Stream.of(publicGetPaths).map(path -> new AntPathRequestMatcher(path, HttpMethod.GET.name())).toArray(AntPathRequestMatcher[]::new)
//                            ).permitAll()
//
//                            // 3. 需要认证的路径
//                            .requestMatchers(new AntPathRequestMatcher("/user/**")).authenticated()
//                            .requestMatchers(new AntPathRequestMatcher("/likes/**")).authenticated()
//                            .requestMatchers(new AntPathRequestMatcher("/collections/**")).authenticated()
//                            .requestMatchers(new AntPathRequestMatcher("/follows/**")).authenticated()
//                            .requestMatchers(new AntPathRequestMatcher("/user/updateAvatar", HttpMethod.PATCH.name())).authenticated()
//                            .requestMatchers(new AntPathRequestMatcher("/articles", HttpMethod.POST.name())).authenticated()
//                            .requestMatchers(new AntPathRequestMatcher("/user/me/password", HttpMethod.PATCH.name())).authenticated()
//
//                            // === 核心修改在这里：为每个写操作路径单独创建 RequestMatcher ===
//                            .requestMatchers(new AntPathRequestMatcher("/articles", HttpMethod.POST.name())).authenticated()
//                            .requestMatchers(new AntPathRequestMatcher("/dynamics", HttpMethod.POST.name())).authenticated()
//                            .requestMatchers(new AntPathRequestMatcher("/{contentType}/{contentId}/comments", HttpMethod.POST.name())).authenticated()
//
//                            .requestMatchers(new AntPathRequestMatcher("/articles/**", HttpMethod.PUT.name())).authenticated()
//                            .requestMatchers(new AntPathRequestMatcher("/dynamics/**", HttpMethod.PUT.name())).authenticated()
//
//                            .requestMatchers(new AntPathRequestMatcher("/articles/**", HttpMethod.DELETE.name())).authenticated()
//                            .requestMatchers(new AntPathRequestMatcher("/dynamics/**", HttpMethod.DELETE.name())).authenticated()
//
//                            // 4. 需要特定角色的路径
//                            .requestMatchers(new AntPathRequestMatcher("/admin/**")).hasRole("ADMIN")
//
//                            // 5. 兜底规则
//                            .anyRequest().authenticated();
//                })
//                .authenticationProvider(authenticationProvider())
//                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
//
//        return http.build();
        // 定义需要公开访问的路径
        String[] publicPostPaths = {
                "/user/register",
                "/user/login",
                "/user/forgot-password",
                "/user/reset-password"
        };
        String[] publicGetPaths = {
                "/feed",
                "/articles",
                "/articles/{id}",
                "/user/{id}/profile",
                "/dynamics",
                "/dynamics/{id}",
                "/{contentType}/{contentId}/comments"
        };

        http
                .csrf(AbstractHttpConfigurer::disable)
                .cors(cors -> cors.configurationSource(corsConfigurationSource()))
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers(new AntPathRequestMatcher("/**", HttpMethod.OPTIONS.name())).permitAll()
                        .requestMatchers(
                                Stream.of(publicPostPaths).map(AntPathRequestMatcher::new).toArray(AntPathRequestMatcher[]::new)
                        ).permitAll()
                        .requestMatchers(
                                Stream.of(publicGetPaths).map(path -> new AntPathRequestMatcher(path, HttpMethod.GET.name())).toArray(AntPathRequestMatcher[]::new)
                        ).permitAll()
                        .anyRequest().authenticated()
                )
                // --- 这是关键修改：直接调用本类中的 @Bean 方法来获取实例 ---
                .authenticationProvider(authenticationProvider())
                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();

    }

}